package com.common.android.utils.audio;

import java.io.File;
import java.io.IOException;
import java.util.Vector;

import com.product.android.business.ApplicationVariable;
import com.product.android.utils.LogUtils;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;

public class AudioPlayer implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener{
	private Vector<onPlayFinishListener> mPlayFinishListeners=new Vector<AudioPlayer.onPlayFinishListener>();
	private Vector<onPlayStopListener> mPlayStopListeners=new Vector<AudioPlayer.onPlayStopListener>();
	private AudioManager mAudioManager;
	private SensorManager mSensorManager;
	private Sensor mSensor;
	private int mMode=AudioManager.MODE_NORMAL;
	private boolean mIsAutoAdjust=true;		//是否自动调整播放模式
	//播放完成监听
	public interface onPlayFinishListener{
		void onFinish();
	}
	//播放中止监听
	public interface onPlayStopListener{
		void onStop();
	}
	//播放模式改变监听
	public interface onModeChangedListener{
		void onModeChanged(int mode);
	}
	private onModeChangedListener mModeChangedListener;
	private static AudioPlayer instance = new AudioPlayer();
	private String mFileName;
	private boolean mbNotPlayNext=false;
	private Uri mUri;
	private MediaPlayer mPlayer;

	public static AudioPlayer getInstance() {
		return instance;
	}
	
	private AudioPlayer(){
		Context context=ApplicationVariable.INSTANCE.applicationContext;
		mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
		mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
		//方位传感器，用于判断用户是否把手机放在耳朵旁边
		mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
	}
	public void play(File paramFile,Context context) throws IllegalArgumentException,IllegalStateException, IOException {
		if (paramFile!=null && paramFile.exists()){
			Uri localUri = Uri.fromFile(paramFile);
			this.mUri = localUri;
			innerPlay(context);	
		}else{
			if (paramFile!=null){
				throw new IllegalArgumentException("file not exists:"+paramFile.getAbsolutePath());	
			}
			else{
				throw new IllegalArgumentException("file not exists: paramFile null");	
			}
		}
	}

	public void play(String paramString,Handler handler,Context context) throws IllegalStateException,IOException {
		this.mFileName = paramString;
		File localFile = new File(paramString);
		if(localFile==null||!localFile.exists()){
			LogUtils.d("debug", "file “"+mFileName+"” not exists");
			this.mFileName="";
			handler.sendEmptyMessage(0);
		}
		play(localFile,context);
	}

	private void innerPlay(Context context) throws IllegalArgumentException,IllegalStateException, IOException {
		Uri localUri = this.mUri;
		if (this.mPlayer != null){
			this.mPlayer.release();
			for(onPlayStopListener listener:mPlayStopListeners){
				listener.onStop();
			}
		}
		this.mPlayer = null;
		MediaPlayer localMediaPlayer = MediaPlayer.create(context, localUri);
		this.mPlayer = localMediaPlayer;
		if(this.mPlayer==null){
			stopPlay();
			return;
		}
		if (mIsAutoAdjust){
			//自动模式，开启感应器监听
			mSensorManager.registerListener(sensorEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
		}
		this.mPlayer.setAudioStreamType(3);
		this.mPlayer.setOnErrorListener(this);
		this.mPlayer.setOnCompletionListener(this);
		this.mPlayer.start();
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		stopPlay(false);// 这边不需要stop回调
		if (mbNotPlayNext){
			mbNotPlayNext=false;
			return;
		}
		for(onPlayFinishListener listener:mPlayFinishListeners){
			listener.onFinish();
		}
	}
	
	/**
	 * 
	 * @n<b>函数名称</b>     :stopPlay
	 * @brief	是否需要回调通知
	 * @see
	 * @since    Ver 1.1
	 * @param  @param needNotify
	 * @return void
	 * @<b>作者</b>          :  huangszh
	 * @<b>创建时间</b>      :  2014-3-11上午11:09:31
	 */
	public void stopPlay(boolean needNotify) {
		if (this.mPlayer != null){
			this.mPlayer.stop();
			this.mPlayer.reset();
			this.mPlayer.release();
			this.mPlayer = null;
			this.mFileName ="";
		}
		//播放完成即把监听移除
		mSensorManager.unregisterListener(sensorEventListener);
		if(!needNotify){
			return;
		}
		for(onPlayStopListener listener:mPlayStopListeners){
			listener.onStop();
		}
	}

	/**
	 * 
	 * @n<b>函数名称</b>     :stopPlay
	 * @brief	默认停止音频时都需要回调通知
	 * @see
	 * @since    Ver 1.1
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  huangszh
	 * @<b>创建时间</b>      :  2014-3-11上午11:14:35
	 */
	public void stopPlay(){
		stopPlay(true);
	}
	
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		stopPlay();
		for(onPlayStopListener listener:mPlayStopListeners){
			listener.onStop();
		}
		return false;
	}

	public String getFileName() {
		return mFileName;
	}
	
	/**
	 * @n<b>函数名称</b>     :setOnPlayFinishListener
	 * @brief 注册播放完成监听事件
	 * @version    Ver 1.3.3_modularization
	 * @param  @param listener
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-2-8下午2:08:30      
	*/
	public void setOnPlayFinishListener(onPlayFinishListener listener){
		mPlayFinishListeners.add(listener);
	}
	
	/**
	 * @n<b>函数名称</b>     :setOnPlayStopListener
	 * @brief 注册播放中止监听事件
	 * @version    Ver 1.3.3_modularization
	 * @param  @param listener
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-2-8下午2:08:49      
	*/
	public void setOnPlayStopListener(onPlayStopListener listener){
		mPlayStopListeners.add(listener);
	}
	
	/**
	 * @n<b>函数名称</b>     :removeOnPlayFinishListener
	 * @brief 移除播放完成监听事件
	 * @version    Ver 1.3.3_modularization
	 * @param  @param listener
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-2-8下午2:09:16      
	*/
	public void removeOnPlayFinishListener(onPlayFinishListener listener){
		synchronized (mPlayFinishListeners) {
			mPlayFinishListeners.remove(listener);
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :removeOnPlayStopListener
	 * @brief 移除播放中止监听事件
	 * @version    Ver 1.3.3_modularization
	 * @param  @param listener
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-2-8下午2:09:16      
	 */
	public void removeOnPlayStopListener(onPlayStopListener listener){
		synchronized (mPlayStopListeners) {
			mPlayStopListeners.remove(listener);
		}
	}
	
	public void setNotPlayNext(boolean next){
		mbNotPlayNext=next;
	}
	
	/**
	 * @n<b>函数名称</b>     :getAudioDuration
	 * @brief 获取语音的播放时间
	 * @version    Ver 1.3.3_modularization
	 * @param  @param fileName
	 * @param  @return
	 * @return int
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-2-12下午6:36:28      
	*/
	public static int getAudioDuration(String fileName){
		if (TextUtils.isEmpty(fileName)){
			return -1;
		}
		int duration = 0;
	    try {
	    	MediaPlayer mDurationPlayer=new MediaPlayer();
	        mDurationPlayer.reset();
	        mDurationPlayer.setDataSource(fileName);
	        mDurationPlayer.prepare();
	        duration = mDurationPlayer.getDuration();
	        mDurationPlayer.stop();
	    } catch (IOException e) {
	    	return -1;
	    } catch (IllegalStateException e) {
	    	return -1;
	    }
	    finally{
	    }
	    return duration;
	}
	
	private SensorEventListener sensorEventListener = new SensorEventListener() {
		@Override
		public void onSensorChanged(SensorEvent event) {
			if (mIsAutoAdjust){
				float range = event.values[0];
				int mode;
				if (range >= mSensor.getMaximumRange()) {
					mode=AudioManager.MODE_NORMAL;
				} else {
					mode=AudioManager.MODE_IN_CALL;
				}
				//设置当前播放模式，并通知界面
				mAudioManager.setMode(mode);
				if (mModeChangedListener!=null && mMode!=mode){
					mModeChangedListener.onModeChanged(mode);
				}
				mMode=mode;
			}
		}

		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {

		}
	};
	
	/**
	 * @n<b>函数名称</b>     :setOnModeChangedListener
	 * @brief 设置模式切换监听
	 * @version    Ver 1.3.3_modularization
	 * @param  @param listener
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-14下午7:33:35      
	*/
	public void setOnModeChangedListener(onModeChangedListener listener){
		mModeChangedListener=listener;
	}
	
	/**
	 * @n<b>函数名称</b>     :unregistModeChangeListener
	 * @brief 移除模式切换监听
	 * @version    Ver 1.3.3_modularization
	 * @param  
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-14下午7:33:48      
	*/
	public void unregistModeChangeListener(){
		mModeChangedListener=null;
	}
	
	/**
	 * @n<b>函数名称</b>     :setMode
	 * @brief 设置播放模式
	 * @version    Ver 1.3.3_modularization
	 * @param  @param mode
	 * @return void
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-14下午7:33:54      
	*/
	public void setMode(int mode){
		mMode=mode;
		mAudioManager.setMode(mode);
		mIsAutoAdjust=(mode==AudioManager.MODE_NORMAL);
		if (mModeChangedListener!=null){
			mModeChangedListener.onModeChanged(mMode);
		}
	}
	
	/**
	 * @n<b>函数名称</b>     :getMode
	 * @brief 获取当前播放模式
	 * @version    Ver 1.3.3_modularization
	 * @param  @return
	 * @return int
	 * @<b>作者</b>          :  cb
	 * @<b>创建时间</b>      :  2014-3-14下午7:34:04      
	*/
	public int getMode(){
		return mMode;
	}
}